//enable sharpening
#define ESHARPENING

//if defined, color sharpen, otherwise sharp by gray
#define ESHARPENINGCOLOR

//enable noise in dark areas
#define ENOISE


float SharpSamplingRange=0.1;//1.0; //sharpening or blurring range
float SamplingRange=0.1; //sharpening or blurring range
float ShiftSamplingRange=0.1;
float SharpeningAmount=0.2;//3.0;
float ScanLineAmount=1;
float ScanLineRepeat=0.125; //0.5, 0.3333, 0.25, 0.125, so on
float NoiseAmount=0;

//keyboard controled variables
float tempF1;
float tempF2;
float tempF3;
float tempF4;
float tempF5;
float tempF6;
float tempF7;
float tempF8;
float tempF9;
float tempF0;

//global variables, already set before executing this code
float ScreenSize; //width of the display resolution (1920 f.e.)
float ScreenScaleY; //screen proportions (1.333 for 1920/1080)

//textures
texture2D texColor;
texture2D texNoise;

sampler2D SamplerColor = sampler_state
{
Texture   = <texColor>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = NONE;//NONE;
AddressU  = Clamp;
AddressV  = Clamp;
SRGBTexture=FALSE;
MaxMipLevel=0;
MipMapLodBias=0;
};

sampler2D SamplerNoise = sampler_state
{
Texture   = <texNoise>;
MinFilter = POINT;
MagFilter = POINT;
MipFilter = NONE;//NONE;
AddressU  = Wrap;
AddressV  = Wrap;
SRGBTexture=FALSE;
MaxMipLevel=0;
MipMapLodBias=0;
};

struct VS_OUTPUT_POST {
float4 vpos  : POSITION;
float2 txcoord : TEXCOORD0;
};

struct VS_INPUT_POST {
float3 pos  : POSITION;
float2 txcoord : TEXCOORD0;
};


//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
VS_OUTPUT_POST VS_PostProcess(VS_INPUT_POST IN)
{
VS_OUTPUT_POST OUT;

float4 pos=float4(IN.pos.x,IN.pos.y,IN.pos.z,1.0);

OUT.vpos=pos;
OUT.txcoord.xy=IN.txcoord.xy;

return OUT;
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//--------------------Fast Approximate Anti-Aliasing --------------------------
//         FXAA v2 CONSOLE by TIMOTHY LOTTES @ NVIDIA   
//          Ported to ENBSeries by MysTer92 (Svyatoslav Gampel)
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
float4 PS_PostProcess(VS_OUTPUT_POST i) : COLOR
{
	#define FXAA_SUBPIX_SHIFT (1.0/8.0)
	#define FXAA_REDUCE_MIN   (1.0/32.0)
	#define FXAA_REDUCE_MUL   (1.0/16.0)
	#define FXAA_SPAN_MAX     8.0
	
	half2 rcpFrame = half2(1/ScreenSize, 1/(ScreenSize/ScreenScaleY));
	
	half4 posPos;
	posPos.xy = i.txcoord.xy;
	posPos.zw = posPos.xy - (rcpFrame.xy * (0.5 + FXAA_SUBPIX_SHIFT));
	
	half3 rgbNW = tex2D(SamplerColor, posPos.zw ).xyz;
	half3 rgbNE = tex2D(SamplerColor, posPos.zw + half2(rcpFrame.x, 0.0) ).xyz;
	half3 rgbSW = tex2D(SamplerColor, posPos.zw + half2(0.0, rcpFrame.y) ).xyz;
	half3 rgbSE = tex2D(SamplerColor, posPos.zw +rcpFrame.xy ).xyz;
	half3 rgbM  = tex2D(SamplerColor, posPos.xy).xyz;
				    
	half3 luma = half3(0.299, 0.587, 0.114);
	half lumaNW = dot(rgbNW, luma);
	half lumaNE = dot(rgbNE, luma);
	half lumaSW = dot(rgbSW, luma);
	half lumaSE = dot(rgbSE, luma);
	half lumaM  = dot(rgbM,  luma);
				    
	half lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
	half lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
				    
	half2 dir; 
				    
	half lumaNWNE = lumaNW + lumaNE;
	half lumaSWSE = lumaSW + lumaSE;
				    
	dir.x = -((lumaNWNE) - (lumaSWSE));
	dir.y =  ((lumaNW + lumaSW) - (lumaNE + lumaSE));
				    
	half dirReduce = max( (lumaSWSE + lumaNWNE) * (0.25 * FXAA_REDUCE_MUL),
									FXAA_REDUCE_MIN);
	half rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce);
	dir = min(half2( FXAA_SPAN_MAX,  FXAA_SPAN_MAX), 
				max(half2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), 
				dir * rcpDirMin)) * rcpFrame.xy;
				          
	half3 rgbA = (1.0/2.0) * (
		tex2D(SamplerColor, posPos.xy + dir * (1.0/3.0 - 0.5) ).xyz +
		tex2D(SamplerColor, posPos.xy + dir * (2.0/3.0 - 0.5) ).xyz);
	half3 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (
		tex2D(SamplerColor, posPos.xy + dir * (0.0/3.0 - 0.5) ).xyz +
		tex2D(SamplerColor, posPos.xy + dir * (3.0/3.0 - 0.5) ).xyz);
	half lumaB = dot(rgbB, luma);
				    
	if((lumaB < lumaMin) || (lumaB > lumaMax))
		return half4(rgbA, 1.0);
				    
	return float4(rgbB, 1.0);
}

float4 PS_PostProcess3(VS_OUTPUT_POST IN, float2 vPos : VPOS) : COLOR
{
float4 res;
float4 coord=0.0;

coord.xy=IN.txcoord.xy;
float4 origcolor;

coord.w=0.0;


origcolor=tex2Dlod(SamplerColor, coord);

// coord.x=IN.txcoord.x-(1.5/ScreenSize);
// float4 lshift=tex2Dlod(SamplerColor, coord);
// coord.x=IN.txcoord.x+(1.5/ScreenSize);
// float4 rshift=tex2Dlod(SamplerColor, coord);


float2 offset[8]=
{
float2(1.0, 1.0),
float2(-1.0, -1.0),
float2(-1.0, 1.0),
float2(1.0, -1.0),

float2(1.41, 0.0),
float2(-1.41, 0.0),
float2(0.0, 1.41),
float2(0.0, -1.41)
};
int i=0;

float4 tcol=origcolor;
float invscreensize=1.0/ScreenSize;
for (i=0; i<8; i++) //higher quality
{
float2 tdir=offset[i].xy;
coord.xy=IN.txcoord.xy+tdir.xy*invscreensize*SamplingRange;//*1.0;
float4 ct=tex2Dlod(SamplerColor, coord);

tcol+=ct;
}
tcol*=0.111; // 1.0/(8+1)  //higher quality



//not interesting
#ifdef EBLURRING
//blur
res=tcol;
#endif


//sharp
#ifdef ESHARPENING

#ifdef ESHARPENINGCOLOR
//color
res=origcolor*(1.0+((origcolor-tcol)*SharpeningAmount));
#else
//non color
float difffact=dot((origcolor.xyz-tcol.xyz), 0.333);
res=origcolor*(1.0+difffact*SharpeningAmount);
#endif

//less sharpening for bright pixels
float rgray=origcolor.z; //blue fit well
rgray=max(origcolor.x, max(origcolor.y, origcolor.z));
rgray=pow(rgray, 3.0);
res=lerp(res, origcolor, saturate(rgray));

#endif




//grain noise
#ifdef ENOISE
float origgray=max(res.x, res.y);//dot(res.xyz, 0.333);
origgray=max(origgray, res.z);
coord.xy=IN.txcoord.xy*16.0 + origgray;
float4 cnoi=tex2Dlod(SamplerNoise, coord);
res=lerp(res, (cnoi.x+1)*res, NoiseAmount*saturate(1.0-origgray*1.0));
#endif


res.w=1.0;
return res;
}

float4 PS_Process4(VS_OUTPUT_POST IN, float2 vPos : VPOS) : COLOR
{
float4 res;
float4 coord=0.0;

coord.xy=IN.txcoord.xy;
float4 origcolor;

coord.w=0.0;


origcolor=tex2Dlod(SamplerColor, coord);

coord.x=IN.txcoord.x-(1.5/ScreenSize);
float4 lshift=tex2Dlod(SamplerColor, coord);
coord.x=IN.txcoord.x+(1.5/ScreenSize);
float4 rshift=tex2Dlod(SamplerColor, coord);


float2 offset[8]=
{
 float2(1.0, 1.0),
 float2(-1.0, -1.0),
 float2(-1.0, 1.0),
 float2(1.0, -1.0),

 float2(1.41, 0.0),
 float2(-1.41, 0.0),
 float2(0.0, 1.41),
 float2(0.0, -1.41)
};
int i=0;

float4 tcol=origcolor;
float2 invscreensize=1.0/ScreenSize;
invscreensize.y=invscreensize.y/ScreenScaleY;
for (i=0; i<8; i++) //higher quality

{
 float2 tdir=offset[i].xy;
 coord.xy=IN.txcoord.xy+tdir.xy*invscreensize*SamplingRange;//*1.0;
 float4 ct=tex2Dlod(SamplerColor, coord);

 tcol+=ct;
}
tcol*=0.111; // 1.0/(8+1)  //higher quality


coord.xy=IN.txcoord.xy;
origcolor=tex2Dlod(SamplerColor, coord);
res.y=origcolor.y;

coord.xy=IN.txcoord.xy;
coord.y-=invscreensize*ShiftSamplingRange;
origcolor=tex2Dlod(SamplerColor, coord);
res.x=origcolor.x;

coord.xy=IN.txcoord.xy;
coord.y+=invscreensize*ShiftSamplingRange;
origcolor=tex2Dlod(SamplerColor, coord);
res.z=origcolor.z;


res.w=1.0;
return res;
}


//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//--------------------Fast Approximate Anti-Aliasing Techniques -------------
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


technique PostProcess
{
   pass P0
   {
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader  = compile ps_3_0 PS_PostProcess();

FogEnable=FALSE;
ALPHATESTENABLE=FALSE;
SEPARATEALPHABLENDENABLE=FALSE;
AlphaBlendEnable=FALSE;
FogEnable=FALSE;
SRGBWRITEENABLE=FALSE;
}
}
technique PostProcess2
{
   pass P0
   {
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader  = compile ps_3_0 PS_PostProcess();

FogEnable=FALSE;
ALPHATESTENABLE=FALSE;
SEPARATEALPHABLENDENABLE=FALSE;
AlphaBlendEnable=FALSE;
FogEnable=FALSE;
SRGBWRITEENABLE=FALSE;
}
}
technique PostProcess3
{
  pass P0
  {

VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader  = compile ps_3_0 PS_PostProcess3();

DitherEnable=FALSE;
ZEnable=FALSE;
CullMode=NONE;
ALPHATESTENABLE=FALSE;
SEPARATEALPHABLENDENABLE=FALSE;
AlphaBlendEnable=FALSE;
StencilEnable=FALSE;
FogEnable=FALSE;
SRGBWRITEENABLE=FALSE;
}
}
technique PostProcess4
{
pass P0
{

 VertexShader = compile vs_3_0 VS_PostProcess();
 PixelShader  = compile ps_3_0 PS_Process4();

 DitherEnable=FALSE;
 ZEnable=FALSE;
 CullMode=NONE;
 ALPHATESTENABLE=FALSE;
 SEPARATEALPHABLENDENABLE=FALSE;
 AlphaBlendEnable=FALSE;
 StencilEnable=FALSE;
 FogEnable=FALSE;
 SRGBWRITEENABLE=FALSE;
}
pass P0
  {
PixelShader = 
asm
{
// Generated by Microsoft (R) HLSL Shader Compiler 9.22.949.2248
//
// Parameters:
//
//   sampler2D SamplerColor;
//   float4 oblv_ReciprocalResolution_MAINPASS;
//
//
// Registers:
//
//   Name                               Reg   Size
//   ---------------------------------- ----- ----
//   oblv_ReciprocalResolution_MAINPASS c0       1
//   SamplerColor                       s0       1
//
//
// Default values:
//
//   oblv_ReciprocalResolution_MAINPASS
//     c0   = { 0, 0, 0, 0 };
//

    ps_3_0
    def c1, 0.298999995, 0.587000012, 0.114, 0
    def c2, -1, 0, 1, 4
    dcl_texcoord v0.xy
    dcl_2d s0
    mov r0.xyz, c2
    mad r1.xy, c0, r0, v0
    texld r1, r1, s0
    mad r2.xy, c0, r0.zyzw, v0
    texld r2, r2, s0
    add r1.xyz, r1, r2
    mad r0.xw, c0.xyzy, r0.yyzx, v0.xyzy
    texld r2, r0.xwzw, s0
    add r1.xyz, r1, r2
    mad r0.xy, c0, r0.yzzw, v0
    texld r0, r0, s0
    add r0.xyz, r1, r0
    texld r1, v0, s0
    mad r0.xyz, r1, -c2.w, r0
    mov oC0.xyz, r1
    mul r0.xyz, r0_abs, c2.w
    dp3 oC0.w, r0, c1

// approximately 17 instruction slots used (5 texture, 12 arithmetic)
};
}
pass P0
  {
PixelShader = 
asm
{
// Generated by Microsoft (R) HLSL Shader Compiler 9.22.949.2248
//
// Parameters:
//
//   sampler2D SamplerColor;
//   float4 oblv_ReciprocalResolution_MAINPASS;
//
//
// Registers:
//
//   Name                               Reg   Size
//   ---------------------------------- ----- ----
//   oblv_ReciprocalResolution_MAINPASS c0       1
//   SamplerColor                       s0       1
//
//
// Default values:
//
//   oblv_ReciprocalResolution_MAINPASS
//     c0   = { 0, 0, 0, 0 };
//

    ps_3_0
    def c1, 0.25, 2, 0.166666672, 0.5
    def c2, 0.298999995, 0.587000012, 0.114, 0.125
    def c3, 3, -0.100000001, 3.5, 0
    def c4, -5.5, 0, -7.5, 0.200000003
    def c5, 0.25, -1, 0, 1
    def c6, -1.5, 0, 1.5, 4
    def c7, 5.5, 0, 7.5, -3.5
    dcl_texcoord v0.xy
    dcl_2d s0
    mov r0.xy, c0
    mad r0.zw, r0.xyxy, c7.xyyx, v0.xyxy
    texld r1, r0.zwzw, s0
    mad r0.zw, r0.xyxy, c3.xywz, v0.xyxy
    texld r2, r0.zwzw, s0
    mad r0.zw, r0.xyxy, c6.xyyz, v0.xyxy
    texld r3, r0.zwzw, s0
    add r2, r2.wxyz, r3.wxyz
    add r1, r1.wxyz, r2
    mad r0.zw, r0.xyxy, c7.xyyz, v0.xyxy
    texld r2, r0.zwzw, s0
    add r1, r1, r2.wxyz
    mad r0.zw, r0.xyxy, c6.xyyx, v0.xyxy
    texld r2, r0.zwzw, s0
    add r1, r1, r2.wxyz
    add r2, r3, r2
    mad r0.zw, r0.xyxy, c7.xyyw, v0.xyxy
    texld r3, r0.zwzw, s0
    add r1, r1, r3.wxyz
    mad r0.zw, r0.xyxy, c4.xyyx, v0.xyxy
    texld r3, r0.zwzw, s0
    add r1, r1, r3.wxyz
    mad r0.zw, r0.xyxy, c4.xyyz, v0.xyxy
    texld r3, r0.zwzw, s0
    add r1, r1, r3.wxyz
    mad_sat r0.z, r1.x, c5.x, c5.y
    mul r1.xyz, r1.yzww, c2.w
    dp3 r0.w, r1, c2
    texld r1, v0, s0
    dp3 r3.x, r1, c2
    add r3.y, r0.w, -r3.x
    mad r3.zw, r0.xyxy, c5.xywz, v0.xyxy
    texld r4, r3.zwzw, s0
    dp3 r3.z, r4, c2
    add r3.z, r3.x, -r3.z
    rcp r3.z, r3.z
    mad_sat r5.y, r3.y, r3.z, c5.w
    mad r3.yz, r0.xxyw, c5, v0.xxyw
    texld r6, r3.yzzw, s0
    dp3 r3.y, r6, c2
    add r0.w, r0.w, -r3.y
    add r3.y, r3.x, -r3.y
    rcp r3.y, r3.y
    mul_sat r5.x, r0.w, r3.y
    mad r3.yz, r0.xxyw, c7.xxyw, v0.xxyw
    texld r7, r3.yzzw, s0
    mad r3.yz, r0.xxyw, c3.xzww, v0.xxyw
    texld r8, r3.yzzw, s0
    mad r3.yz, r0.xxyw, c6.xzyw, v0.xxyw
    texld r9, r3.yzzw, s0
    add r8, r8.wxyz, r9.wxyz
    add r7, r7.wxyz, r8
    mad r3.yz, r0.xxyw, c7.xzyw, v0.xxyw
    texld r8, r3.yzzw, s0
    add r7, r7, r8.wxyz
    mad r3.yz, r0.xxyw, c6.xxyw, v0.xxyw
    texld r8, r3.yzzw, s0
    add r7, r7, r8.wxyz
    add r8, r9, r8
    mad r3.yz, r0.xxyw, c7.xwyw, v0.xxyw
    texld r9, r3.yzzw, s0
    add r7, r7, r9.wxyz
    mad r3.yz, r0.xxyw, c4.xxyw, v0.xxyw
    texld r9, r3.yzzw, s0
    add r7, r7, r9.wxyz
    mad r3.yz, r0.xxyw, c4.xzyw, v0.xxyw
    texld r9, r3.yzzw, s0
    add r7, r7, r9.wxyz
    mul r3.yzw, r7, c2.w
    mad_sat r0.w, r7.x, c5.x, c5.y
    dp3 r3.y, r3.yzww, c2
    add r3.z, -r3.x, r3.y
    mad r7.xy, r0, c5.zwzw, v0
    texld r7, r7, s0
    dp3 r3.w, r7, c2
    add r3.w, r3.x, -r3.w
    rcp r3.w, r3.w
    mad_sat r5.w, r3.z, r3.w, c5.w
    mad r0.xy, r0, c5.zyzw, v0
    texld r9, r0, s0
    dp3 r0.x, r9, c2
    add r0.xy, r3, -r0.x
    rcp r0.x, r0.x
    mul_sat r5.z, r0.y, r0.x
    cmp r3, -r5, c5.w, r5
    lrp r5, r3.x, r1, r6
    lrp r6, r3.y, r5, r4
    add r4.xyz, r2, r2
    mad r4.xyz, r1, -c6.w, r4
    mul r4.xyz, r4_abs, c1.x
    dp3 r0.x, r4, c2
    mad r0.x, r0.x, c3.x, c3.y
    add r4, r1, r1
    mad r5, r8, c1.y, r4
    add r8.xyz, r8, r8
    mad r8.xyz, r1, -c6.w, r8
    mul r8.xyz, r8_abs, c1.x
    dp3 r0.y, r8, c2
    mad r0.y, r0.y, c3.x, c3.y
    mad r2, r2, c1.y, r4
    mul r4.xyz, r5, c1.z
    mad r5, r5, c1.z, -r1
    dp3 r3.x, r4, c2
    rcp r3.x, r3.x
    mul_sat r0.x, r0.x, r3.x
    mad r4, r0.x, r5, r1
    lrp r5, r3.z, r1, r9
    lrp r1, r3.w, r5, r7
    mad r3, r2, c1.z, -r4
    mul r2.xyz, r2, c1.z
    dp3 r0.x, r2, c2
    rcp r0.x, r0.x
    mul_sat r0.x, r0.y, r0.x
    mul r0.x, r0.x, c1.w
    mad r2, r0.x, r3, r4
    lrp r3, r0.z, r6, r2
    add r0.x, -r0.z, r0.w
    lrp r4, r0.w, r1, r3
    add r0.x, -r0_abs.x, c4.w
    cmp oC0, r0.x, r2, r4

// approximately 120 instruction slots used (21 texture, 99 arithmetic)
};
}
}

